package com.itheima.prize.api.action;

import com.alibaba.fastjson.JSON;
import com.itheima.prize.api.config.LuaScript;
import com.itheima.prize.commons.config.RabbitKeys;
import com.itheima.prize.commons.config.RedisKeys;
import com.itheima.prize.commons.db.entity.*;
import com.itheima.prize.commons.db.mapper.CardGameMapper;
import com.itheima.prize.commons.db.service.CardGameService;
import com.itheima.prize.commons.db.service.CardUserHitService;
import com.itheima.prize.commons.utils.ApiResult;
import com.itheima.prize.commons.utils.RedisUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;

@RestController
@RequestMapping("/api/act")
@Api(tags = {"抽奖模块"})
public class ActController {

    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private LuaScript luaScript;

    @Autowired
    private CardUserHitService cardUserHitService;


    @GetMapping("/go/{gameid}")
    @ApiOperation(value = "抽奖")
    @ApiImplicitParams({
            @ApiImplicitParam(name="gameid",value = "活动id",example = "1",required = true)
    })
    public ApiResult<Object> act(@PathVariable int gameid, HttpServletRequest request){

        CardProduct hitProduct = new CardProduct();
        CardUser user = (CardUser)request.getSession().getAttribute("user");
        Integer userId = user.getId();
        Integer userLevel = user.getLevel();
        if(redisUtil.get(RedisKeys.USERENTER+gameid+"_"+ user.getId()) == null){
            redisUtil.set(RedisKeys.USERENTER+gameid+"_"+ user.getId(),1);
        }

        Date Dtime = new Date();
        long time = Dtime.getTime();
        CardGame game= (CardGame)redisUtil.get(RedisKeys.INFO + gameid);
        //各种判断，包括时间，是否登录，抽奖次数
        if (time < game.getStarttime().getTime()){
            return new ApiResult<>(-1,"活动未开始", null);
        }else if (time > game.getEndtime().getTime()){
            return new ApiResult<>(-1,"活动已结束", null);
        }else if (user == null){
            return new ApiResult<>(-1,"未登录", null);
        }else if((Integer)redisUtil.get(RedisKeys.USERENTER+gameid+"_"+user.getId())>=
                (Integer)redisUtil.hget(RedisKeys.MAXENTER+gameid,String.valueOf(userLevel))){
            return new ApiResult<>(-1,"您的抽奖次数已用完", null);
        }
        redisUtil.incr(RedisKeys.USERENTER + gameid+"_" + userId,1);//这里写在成功抽奖代码里
        rabbitTemplate.convertAndSend(RabbitKeys.QUEUE_PLAY,JSON.toJSONString(new CardUserGame(userId,gameid,Dtime)));

        //开始抽奖
        luaScript.init();
        Long hitToken = luaScript.tokenCheck(RedisKeys.TOKENS  + gameid, String.valueOf(time));
        if (hitToken == 0){
            return new ApiResult<>(-1,"奖品已抽光", null);
        } else if (hitToken == 1) {
            return new ApiResult<>(-1,"未中奖", null);
        }
        CardProductDto hitproductdto = (CardProductDto)redisUtil.get(RedisKeys.TOKEN + gameid + "_" + hitToken);
        BeanUtils.copyProperties(hitproductdto,hitProduct);

        //rabbitmq发送消息
        rabbitTemplate.convertAndSend(RabbitKeys.QUEUE_HIT,JSON.toJSONString(new CardUserHit(gameid,userId,hitProduct.getId(),Dtime)));

        //持久化中奖信息
        //redisUtil.set(RedisKeys.USERHIT+gameid+"_"+userId,hitProduct,-1);
        //cardUserHitService.save(new CardUserHit(gameid,userId,hitProduct.getId()));

        return new ApiResult<>(1,"恭喜中奖", hitProduct);


    }

    @GetMapping("/info/{gameid}")
    @ApiOperation(value = "缓存信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name="gameid",value = "活动id",example = "1",required = true)
    })
    public ApiResult info(@PathVariable int gameid){
        Object info = redisUtil.get(RedisKeys.INFO + gameid);

        if (info == null){
            return new ApiResult<>(0,"活动不存在", null);
        }
        Map gamemap =new HashMap();
        Map map = new HashMap();
        //Long realtime = null;

        List<Object> tokens = redisUtil.lrange(RedisKeys.TOKENS + gameid, 0, -1);
        tokens.forEach(token -> {
            CardProduct product = (CardProduct) redisUtil.get(RedisKeys.TOKEN + gameid +"_"+token);
            Long tokena = (Long) token;
            Long realtime = tokena/1000000;
            LocalDateTime dateTime = LocalDateTime.ofInstant(
                    Instant.ofEpochSecond(realtime), // 秒级时间戳转 Instant
                    ZoneId.of("Asia/Shanghai")       // 指定时区（北京时间）
            );
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            String timeStr = dateTime.format(formatter);

            map.put(timeStr,product);
        });
        Object maxgoal = redisUtil.hget(RedisKeys.MAXGOAL + gameid, "1");
        Object maxenter = redisUtil.hget(RedisKeys.MAXENTER + gameid, "1");
        gamemap.put(RedisKeys.INFO + gameid,info);
        gamemap.put(RedisKeys.TOKENS + gameid,map);
        gamemap.put(RedisKeys.MAXGOAL + gameid,maxgoal);
        gamemap.put(RedisKeys.MAXENTER + gameid,maxenter);
        return new ApiResult<>(1,"成功",gamemap);
    }

}
